package co.fitstart.coach.dao;

import java.util.Date;
import java.util.List;
import java.util.Set;

import com.demo2do.core.persistence.annotation.Dynamic;
import com.demo2do.core.persistence.annotation.Execute;
import com.demo2do.core.persistence.annotation.Limit;
import com.demo2do.core.persistence.annotation.Query;
import com.demo2do.core.persistence.annotation.Variable;

import co.fitstart.entity.course.Course;
import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.course.schedule.ScheduleStatus;
import co.fitstart.entity.courseware.CoursewareTag;
import co.fitstart.entity.courseware.FitnessTag;
import co.fitstart.entity.courseware.dietary.DietaryProgram;
import co.fitstart.entity.courseware.dietary.DietaryProgramType;
import co.fitstart.entity.courseware.exercise.PlannedSchedule;
import co.fitstart.entity.courseware.fitnessgroup.BatchCourseware;
import co.fitstart.entity.courseware.fitnessgroup.BatchCoursewareType;
import co.fitstart.entity.courseware.fitnessgroup.Courseware;
import co.fitstart.entity.courseware.fitnessgroup.DailyCourseware;
import co.fitstart.entity.courseware.fitnessgroup.FitnessGroup;
import co.fitstart.entity.courseware.movement.Movement;

@Dynamic("hibernate")
public interface CoursewareDao {
    
    /**
     * 
     * @param courseRound
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND editStatus != 2")
    public List<BatchCourseware> listBatchCourseware(@Variable("courseRound") CourseRound courseRound);
    
    /**
     * 
     * @param courseRound
     * @param type
     * @param beginIndex
     * @param maxResult
     * @return
     */
    @Limit
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type AND editStatus != 2 ORDER BY sorting")
    public BatchCourseware getBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type, @Variable("beginIndex") int beginIndex, @Variable("maxResult") int maxResult);
    
    /**
     * 
     * @param courseRound
     * @param type
     * @param sorting
     * @return
     */
    @Query("FROM BatchCourseware WHERE disabled = false AND courseRound = :courseRound AND type = :type AND sorting = :sorting")
    public BatchCourseware getBatchCourseware(@Variable("courseRound") CourseRound courseRound, @Variable("type") BatchCoursewareType type, @Variable("sorting") int sorting);
    
    /**
     * 
     * @param batch
     * @param beginIndex
     * @param maxResult
     * @return
     */
    @Limit
    @Query("FROM DailyCourseware WHERE disabled = false AND batch = :batch AND editStatus != 2 ORDER BY sorting")
    public DailyCourseware getDailyCourseware(@Variable("batch") BatchCourseware batch, @Variable("beginIndex") int beginIndex, @Variable("maxResult") int maxResult);
    
    /**
     * 
     * @param batch
     * @param sorting
     * @return
     */
    @Query("FROM DailyCourseware WHERE disabled = false AND batch = :batch AND sorting = :sorting")
    public DailyCourseware getDailyCourseware(@Variable("batch") BatchCourseware batch, @Variable("sorting") int sorting);
    
    /**
     * 
     * @param batch
     * @return
     */
    @Query("FROM DailyCourseware WHERE disabled = false AND batch = :batch AND editStatus != 2")
    public List<DailyCourseware> listDailyCourseware(@Variable("batch") BatchCourseware batch);
    
    /**
     * 
     * @param dailyCourseware
     * @return
     */
    @Query("FROM Courseware WHERE disabled = false AND daily = :daily ORDER BY type, id")
    public List<Courseware> listCourseware(@Variable("daily") DailyCourseware dailyCourseware);
    
    /**
     * 
     * @param course
     * @return
     */
    @Query("FROM FitnessGroup WHERE disabled = false AND course = :course AND type != 2")
    public List<FitnessGroup> listFitnessGroup(@Variable("course") Course course);
    
    /**
     * 
     * @param FitnessGroupId
     * @param course
     * @return
     */
    @Query("FROM FitnessGroup WHERE disabled = false AND id != :fitnessGroupId AND course = :course AND type != 2")
    public List<FitnessGroup> listFitnessGroup(@Variable("fitnessGroupId") Long FitnessGroupId, @Variable("course") Course course);
    
    /**
     * 
     * @param ids
     * @return
     */
    @Query("FROM FitnessTag WHERE disabled = false AND id in (:ids)")
    public List<FitnessTag> listFitnessTag(@Variable("ids") List<Long> ids);
    
    /**
     * 
     * @param ids
     * @return
     */
    @Query("FROM CoursewareTag WHERE disabled = false AND id in (:ids)")
    public List<CoursewareTag> listCoursewareTag(@Variable("ids") List<Long> ids);
    
    /**
     * 
     * @param dailyCourseware
     */
    @Execute("UPDATE Courseware SET disabled = true WHERE disabled = false AND daily = :daily") 
    public void deleteCourseware(@Variable("daily") DailyCourseware dailyCourseware);
    
    /**
     * 
     * @param batch
     */
    @Execute("UPDATE DailyCourseware SET roundwareStatus = 2, editStatus = 2 WHERE disabled = false AND batch = :batch AND editStatus = 1")
    public void updateDailyStatus(@Variable("batch") BatchCourseware batch);
    
    /**
     * 
     * @param batch
     * @param webLink
     */
    @Execute("UPDATE DailyCourseware SET roundwareStatus = 2, editStatus = 2, webLink = :webLink WHERE disabled = false AND batch = :batch AND editStatus = 1")
    public void updateDailyStatus(@Variable("batch") BatchCourseware batch, @Variable("webLink") String webLink);
    
    /**
     * 
     * @param batchCourseware
     * @param type
     * @return
     */
    @Query("FROM DietaryProgram WHERE disabled = false AND batch = :batch AND type = :type")
    public DietaryProgram loadDietaryProgram(@Variable("batch") BatchCourseware batchCourseware, @Variable("type") DietaryProgramType type);
    
    /**
     * 
     * @param courseRound
     * @param scheduleStatus
     * @param occurDate
     * @param occurHour
     * @return
     */
    @Query("SELECT COUNT(*) FROM CourseSchedule WHERE disabled=false AND courseRound=:courseRound AND scheduleStatus IN (:scheduleStatus) AND (occurDate<:occurDate OR (occurDate=:occurDate AND occurHour<=:occurHour))")
    public int getRank(@Variable("courseRound") CourseRound courseRound,
            @Variable("scheduleStatus") ScheduleStatus[] scheduleStatus, @Variable("occurDate") Date occurDate,
            @Variable("occurHour") String occurHour);

    /**
     * 
     * @param courseSchedule
     * @return
     */
    @Query("FROM Courseware WHERE disabled=false AND courseSchedule=:courseSchedule ORDER BY id ASC")
    public List<Courseware> listCourseware(@Variable("courseSchedule") CourseSchedule courseSchedule);
    
    /**
     * 
     * @param courseRound
     * @param beginIndex
     * @param maxResult
     * @return
     */
    @Limit
    @Query("FROM PlannedSchedule WHERE disabled=false AND content IS NOT NULL AND batch.courseRound=:courseRound ORDER BY batch.sorting ASC,day ASC")
    public List<PlannedSchedule> getPlannedSchedule(@Variable("courseRound") CourseRound courseRound, @Variable("beginIndex") int beginIndex, @Variable("maxResult") int maxResult);
    
    /**
     * 
     * @param name
     * @return
     */
    @Query("FROM Movement WHERE disabled=false AND name=:name")
    public Movement getMovementByName(@Variable("name") String name);
    
    /**
     * 
     * @param categorys
     * @return
     */
    @Query("FROM Movement WHERE disabled=false AND category.name IN (:categorys)")
    public List<Movement> listMovement(@Variable("categorys") Set<String> categorys);
    
    /**
     * 
     * @param batchs
     * @return
     */
    @Execute("UPDATE Dietary SET disabled = true WHERE batch IN (:batchs)")
    public void disableDietary(@Variable("batchs") List<BatchCourseware> batchs);
}
